package com.fast.common.utils;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class PropertiesUtil {


    /**
     * 将源对象复制为目标类型的对象
     *
     * @param source      源对象
     * @param targetClass 目标类型
     * @param <T>         目标类型的类型参数
     * @return 目标类型的对象
     */
    public static <T> T copy(Object source, Class<T> targetClass) {
        String jsonString = JSONObject.toJSONString(source);
        return JSONObject.parseObject(jsonString, targetClass);
    }

    /**
     * 将源列表复制为目标类型的列表
     *
     * @param source      源列表
     * @param targetClass 目标类型
     * @param <T>         目标类型的类型参数
     * @return 目标类型的列表
     */
    public static <T> List<T> copyList(Collection<?> source, Class<T> targetClass) {
        String jsonString = JSONArray.toJSONString(source);
        return JSONArray.parseArray(jsonString, targetClass);
    }

    /**
     * 将源对象复制为目标类型的对象,并设置目标对象的指定属性值
     *
     * @param source        源对象
     * @param targetClass   目标类型
     * @param propertyName  要设置的属性名
     * @param propertyValue 要设置的属性值
     * @param <T>           目标类型的类型参数
     * @return 目标类型的对象
     */
    public static <T> T copy(Object source, Class<T> targetClass, String propertyName, Object propertyValue) {
        T target = copy(source, targetClass);
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(target));
        jsonObject.put(propertyName, propertyValue);
        return jsonObject.toJavaObject(targetClass);
    }

    /**
     * 将源列表复制为目标类型的列表,并设置目标列表中每个对象的指定属性值
     *
     * @param source        源列表
     * @param targetClass   目标类型
     * @param propertyName  要设置的属性名
     * @param propertyValue 要设置的属性值
     * @param <T>           目标类型的类型参数
     * @return 目标类型的列表
     */
    public static <T> List<T> copy(List<?> source, Class<T> targetClass, String propertyName, Object propertyValue) {
        List<T> targetList = new ArrayList<>();
        for (Object obj : source) {
            T target = JSONObject.parseObject(JSONObject.toJSONString(obj), targetClass);
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(target));
            jsonObject.put(propertyName, propertyValue);
            targetList.add(jsonObject.toJavaObject(targetClass));
        }
        return targetList;
    }

    /**
     * 将源列表复制为目标类型的列表,并对每个元素执行自定义转换操作
     *
     * @param source 源列表
     * @param mapper 自定义转换函数
     * @param <S>    源类型的类型参数
     * @param <T>    目标类型的类型参数
     * @return 目标类型的列表
     */
    public static <S, T> List<T> copyAndMap(List<S> source, Function<S, T> mapper) {
        return source.stream()
                .map(mapper)
                .collect(Collectors.toList());
    }

    /**
     * 将源列表复制为目标类型的列表,并过滤掉不满足条件的元素
     *
     * @param source    源列表
     * @param predicate 过滤条件
     * @param <T>       源类型和目标类型的类型参数
     * @return 目标类型的列表
     */
    public static <T> List<T> copyAndFilter(List<T> source, Function<T, Boolean> predicate) {
        return source.stream()
                .filter(predicate::apply)
                .collect(Collectors.toList());
    }
}
